"""
Case Type   : 资源池化双集群
Case Name   : 资源池化双集群主集群主节点读写、主集群备节点空载、备集群空载下, 备集群内进行 failover 操作
Create At   : 2025-05-15
Owner       : hejiahuan
Description :
    1. 查看主备集群状态 cm_ctl query -Cv
    2. 主节点执行tpcc读写业务, 备节点空载，备集群空载
    3. 备集群内执行failover, 并查看集群状态 cm_ctl query -Cv
    4. failover节点进行节点启动并查看集群状态 cm_ctl start -n 1 , cm_ctl query -Cv
    5. 恢复集群为初始状态 cm_ctl switchover -a
Expect      :
    1. 集群状态正常
    2. 业务执行成功
    3. 成功,集群状态符合预期
    4. 成功,集群状态符合预期
    5. 成功
History     :
    1. 2025-05-15 创建
"""
import os
import unittest
import time
from testcase.utils.Logger import Logger
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.ComThread import ComThread
from testcase.utils.Common import Common
from yat.test import Node
from yat.test import macro
log = Logger()
P_Primary_SH = CommonSH('P_PrimaryDbUser')
S_Primary_SH = CommonSH('S_PrimaryDbUser')

@unittest.skipIf(1 == P_Primary_SH.exec_cm_ctl('list', '--param --server | grep ss_double_cluster_mode').split('=')[-1].strip(), '非双集群环境下不执行')
class Dual_Cluster_NormalCase_Case00013(unittest.TestCase):

    def setUp(self):
        log.info(f'-----{os.path.basename(__file__)} start-----')
        self.constant = Constant()
        self.com = Common()
        self.P_Primary = Node('P_PrimaryRoot')

    def test_shared_storage(self):
        text = '-----step1:查看主备集群状态; expect:集群状态正常-----'
        log.info(text)
        status = P_Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)
        status = S_Primary_SH.exec_cm_ctl(mode='query', param='-Cv', env=macro.DB_STANDBY_ENV_PATH)
        log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)
        status = P_Primary_SH.check_data_consistency()
        self.assertTrue(status, '容灾关系断开' + text)

        text = '-----step2:主节点执行读写业务，备节点空载，备集群空载  expect:启动业务成功-----'
        log.info(text)
        tpcc_cmd_p = f'./runBenchmark.sh {macro.PRI_P_PROPS}'
        tpcc_thread_p = ComThread(self.com.startTPCC,
                                  args=(self.P_Primary,
                                        macro.TPCC_PATH,
                                        tpcc_cmd_p))
        tpcc_thread_p.setDaemon(True)
        tpcc_thread_p.start()

        text = '-----step3:备集群内执行failover; expect:执行成功-----'
        log.info(text)
        stopdn = S_Primary_SH.exec_failover(gaussdb_binary_path=macro.GAUSSDB_STANDBY_PATH)
        log.info(stopdn)
        time.sleep(50)
        status = S_Primary_SH.exec_cm_ctl(mode='query', param='-Cv', env=macro.DB_STANDBY_ENV_PATH)
        log.info(status)
        res1 = status.splitlines()[-1].split('|')[0].split('6001')[-1]
        res2 = status.splitlines()[-1].split('|')[1].split('6002')[-1]
        log.info(res1)
        log.info(res2)
        self.assertIn('P Down    Manually stopped', res1, '执行失败' + text)
        self.assertIn('S Main Standby Normal', res2, '执行失败' + text)
        status = P_Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        log.info(status)
        res1 = status.splitlines()[-1].split('|')[0].split('6001')[-1]
        res2 = status.splitlines()[-1].split('|')[1].split('6002')[-1]
        log.info(res1)
        log.info(res2)
        self.assertIn('P Primary Normal', res1, '执行失败' + text)
        self.assertIn('S Standby Normal', res2, '执行失败' + text)
        time.sleep(60)
        status = P_Primary_SH.check_data_consistency()
        self.assertTrue(status, '容灾关系断开' + text)

        text = '-----step4:failover节点进行节点启动; expect:执行成功-----'
        log.info(text)
        startdn = S_Primary_SH.exec_cm_ctl('start', param='-n 1', env=macro.DB_STANDBY_ENV_PATH)
        log.info(startdn)
        self.assertIn(self.constant.cm_start_node_success_msg, startdn,
                '拉起dn节点失败')
        status = S_Primary_SH.exec_cm_ctl(mode='query', param='-Cv', env=macro.DB_STANDBY_ENV_PATH)
        log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)
        res1 = status.splitlines()[-1].split('|')[0].split('6001')[-1]
        log.info(res1)
        self.assertIn('P Standby Normal', res1, '执行失败' + text)

    def tearDown(self):
        text = '-----step5:恢复环境为初始集群状态; expect:成功-----'
        log.info(text)
        status = S_Primary_SH.exec_cm_ctl(mode='query', param='-Cv', env=macro.DB_STANDBY_ENV_PATH)
        log.info(status)
        status = S_Primary_SH.exec_cm_ctl(mode='stop', env=macro.DB_STANDBY_ENV_PATH)
        log.info(status)
        self.assertIn('successfully', status, '执行失败' + text)

        status = S_Primary_SH.exec_cm_ctl(mode='start', env=macro.DB_STANDBY_ENV_PATH)
        log.info(status)
        self.assertIn('successfully', status, '执行失败' + text)

        recovery_switchover = S_Primary_SH.exec_cm_ctl(mode='switchover', param='-a', env=macro.DB_STANDBY_ENV_PATH)
        log.info(recovery_switchover)
        self.assertIn(self.constant.cm_switchover_success_msg, recovery_switchover,
                      '执行失败' + text)

        status = S_Primary_SH.exec_cm_ctl(mode='query', param='-Cv', env=macro.DB_STANDBY_ENV_PATH)
        log.info(status)
        self.assertIn('P Main Standby Normal',
                      status.splitlines()[-1].split('|')[0].split('6001')[-1],
                      '执行失败' + text)
        self.assertIn('S Standby Normal',
                      status.splitlines()[-1].split('|')[1].split('6002')[-1],
                      '执行失败' + text)
        time.sleep(60)
        status = P_Primary_SH.check_data_consistency()
        self.assertTrue(status, '容灾关系断开' + text)
        log.info(f'-----{os.path.basename(__file__)} end-----')